package com.yuan.member.service.impl;

import cn.common.constant.BalanceConstant;
import cn.common.exception.BusinessException;
import cn.common.utils.UserContextUtils;
import cn.model.Balance;
import cn.model.Member;
import cn.model.TansferInfo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yuan.common.redis.constant.CacheConstants;
import com.yuan.common.redis.lock.RedisDistributedLock;
import com.yuan.common.redis.service.RedisRepository;
import com.yuan.member.mapper.BalanceMapper;
import com.yuan.member.mapper.TansferInfoMapper;
import com.yuan.member.service.BalanceService;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

@Slf4j
@Service
public class BalanceServiceImpl extends ServiceImpl<BalanceMapper,Balance> implements BalanceService {
    @Autowired
    private RedisRepository redisRepository;
    @Autowired
    private BalanceMapper balanceMapper;

    @Autowired
    private TansferInfoMapper tansferInfoMapper;
    @Override
    public List<Balance> list(String UserId) {
        QueryWrapper<Balance> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", UserId);
        return  balanceMapper.selectList(queryWrapper);

    }
//    public boolean transferBalances(String currency, BigDecimal balance, BalanceConstant.Move_Type move_type) {
//        String userId = UserContextUtils.getCurrentUserId();
//        log.info("用户:{} 执行转账操作，类型:{}，金额:{}", userId, move_type, balance);
//
//        try {
//            moveBalance(currency, userId, balance, move_type);
//            return true;
//        } catch (BusinessException e) {
//            log.error("转账失败: {}", e.getMessage());
//            return false;
//        } catch (Exception e) {
//            log.error("转账过程发生未知异常", e);
//            return false;
//        }
//    }

//    @Transactional(rollbackFor = Exception.class)
//    public void moveBalance(String currency, String userId, BigDecimal balance, BalanceConstant.Move_Type moveType) {
//        RedisDistributedLock redisDistributedLock = new RedisDistributedLock(redisRepository.getRedisTemplate());
//        String lockKey = CacheConstants.MEMBER_BALANCE_COIN_KEY + userId;
//        boolean lockAcquired = false;
//
//        try {
//            // 尝试获取锁，增加重试次数和等待时间
//            lockAcquired = redisDistributedLock.lock(lockKey, 5000, 10, 200);
//
//            if (!lockAcquired) {
//                throw new BusinessException("系统繁忙，请稍后再试");
//            }
//
//            log.info("用户:{} 获取锁成功，开始处理转账", userId);
//
//            // 查询用户余额
//            QueryWrapper<Balance> queryWrapper = new QueryWrapper<>();
//            queryWrapper.eq("user_id", userId);
//            queryWrapper.eq("currency", currency);
//            Balance member = balanceMapper.selectOne(queryWrapper);
//
//            if (member == null) {
//                throw new BusinessException("用户账户不存在");
//            }
//
//            // 根据转账类型处理余额
//            if (moveType.equals(BalanceConstant.Move_Type.BALANCE_MOVE_TOKEN)) {
//                log.info("类型 {}，当前余额: {}", moveType, member.getBalance());
//                if (member.getBalance().compareTo(balance) < 0) {
//                    throw new BusinessException("余额不够");
//                }
//
//                member.setBalance(member.getBalance().subtract(balance));
//                member.setTokenBalance(member.getTokenBalance().add(balance));
//                log.info("执行 BALANCE_MOVE_TOKEN，新余额: {}, 新代币余额: {}",
//                        member.getBalance(), member.getTokenBalance());
//            }
//            else if (moveType.equals(BalanceConstant.Move_Type.TOKEN_MOVE_BALANCE)) {
//                log.info("类型 {}，当前代币余额: {}", moveType, member.getTokenBalance());
//                if (member.getTokenBalance().compareTo(balance) < 0) {
//                    throw new BusinessException("代币余额不够");
//                }
//
//                member.setTokenBalance(member.getTokenBalance().subtract(balance));
//                member.setBalance(member.getBalance().add(balance));
//                log.info("执行 TOKEN_MOVE_BALANCE，新代币余额: {}, 新余额: {}",
//                member.getTokenBalance(), member.getBalance());
//            }
//
//            // 更新余额
//            int updateCount = balanceMapper.updateById(member);
//            if (updateCount != 1) {
//                throw new BusinessException("余额更新失败");
//            }
//
//            log.info("用户:{} 余额更新成功，添加转账记录", userId);
//
//            // 添加转账记录
//            TansferInfo tansferInfo = new TansferInfo(userId, moveType, currency, balance, member.getTokenBalance());
//            tansferInfoMapper.insert(tansferInfo);
//
//        } finally {
//            // 确保锁被释放
//            if (lockAcquired) {
//                redisDistributedLock.releaseLock(lockKey);
//                log.info("用户:{} 释放锁成功", userId);
//            }
//        }
//    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean transferBalances(String currency,BigDecimal balance, BalanceConstant.Move_Type move_type) {
        String userId = UserContextUtils.getCurrentUserId();
        System.out.println("用户:"+userId);
        try {
            moveBalance(currency, userId, balance, move_type);
            return true;
        } catch (BusinessException e) {
            log.error("转账失败: {}", e.getMessage());
            return false;
        } catch (Exception e) {
            log.error("转账过程发生未知异常", e);
            return false;
        }
    }
    public void moveBalance(String currency, String userId, BigDecimal balance, BalanceConstant.Move_Type moveType) throws InterruptedException {
        RedisDistributedLock redisDistributedLock =  new RedisDistributedLock(redisRepository.getRedisTemplate());
        boolean lock_coin = redisDistributedLock.lock(CacheConstants.MEMBER_BALANCE_COIN_KEY + userId,
                5000, 50, 100);
        if(lock_coin){
            System.out.println("执行获取的锁:"+lock_coin);
            QueryWrapper<Balance> queryWrapper =  new QueryWrapper<>();
            queryWrapper.eq("user_id", userId);
            queryWrapper.eq("currency", currency);
            Balance member = balanceMapper.selectOne(queryWrapper);
            if(moveType.equals(BalanceConstant.Move_Type.BALANCE_MOVE_TOKEN)){
                log.info("类型 {} {}",moveType,member.getBalance());
                 if(member.getBalance().compareTo(balance)< 0){
                      throw new BusinessException("余额不够");
                 }

                member.setBalance(member.getBalance().subtract(balance));
                member.setTokenBalance(member.getTokenBalance().add(balance));
                System.out.println("执行的次数okok:"+member.getTokenBalance());
            }
            if(moveType.equals(BalanceConstant.Move_Type.TOKEN_MOVE_BALANCE)){
                log.info("类型 {} {}",moveType,member.getTokenBalance());
                if(member.getTokenBalance().compareTo(balance)< 0){
                    throw new BusinessException("余额不够");
                }
                member.setTokenBalance(member.getTokenBalance().subtract(balance));
                member.setBalance(member.getBalance().add(balance));
            }
            int is = balanceMapper.updateById(member);
            System.out.println("修改成功:"+is);
            TansferInfo tansferInfo = new TansferInfo(userId, moveType, currency, balance, member.getTokenBalance());
            tansferInfoMapper.insert(tansferInfo);
            //Thread.sleep(10000);
            //解锁
            redisDistributedLock.releaseLock(CacheConstants.MEMBER_BALANCE_COIN_KEY + userId);
        }
    }
    public List<Balance> getBalances(String Currency) {
        String MemberId = UserContextUtils.getCurrentUserId();
        QueryWrapper<Balance> queryWrapper = new QueryWrapper<>();
        if(Strings.isNotBlank(Currency)){
            queryWrapper.eq("currency", Currency);
        }
        queryWrapper.eq("user_id", MemberId);
        return  balanceMapper.selectList(queryWrapper);
    }
}
